package com.southminority.ethnic.service.contact.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.southminority.ethnic.common.exception.BusinessException;
import com.southminority.ethnic.common.result.PageResult;
import com.southminority.ethnic.mapper.contact.ContactInfoMapper;
import com.southminority.ethnic.mapper.MapLocationConfigMapper;
import com.southminority.ethnic.pojo.ContactInfo;
import com.southminority.ethnic.pojo.MapLocationConfig;
import com.southminority.ethnic.service.contact.ContactInfoService;
import com.southminority.ethnic.controller.contact.vo.ContactInfoVO;
import com.southminority.ethnic.vo.MapLocationConfigVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 联系信息服务实现类
 * 
 * @author SouthMinority
 */
@Slf4j
@Service
@Transactional
public class ContactInfoServiceImpl implements ContactInfoService {

    private final ContactInfoMapper contactInfoMapper;
    private final MapLocationConfigMapper mapLocationConfigMapper;
    private final ObjectMapper objectMapper;

    // 联系方式类型映射
    private static final Map<String, String> TYPE_DISPLAY_MAP = new HashMap<>();
    static {
        TYPE_DISPLAY_MAP.put("address", "联系地址");
        TYPE_DISPLAY_MAP.put("phone", "联系电话");
        TYPE_DISPLAY_MAP.put("email", "电子邮箱");
        TYPE_DISPLAY_MAP.put("website", "官方网站");
        TYPE_DISPLAY_MAP.put("social", "社交媒体");
    }

    public ContactInfoServiceImpl(ContactInfoMapper contactInfoMapper, 
                                  MapLocationConfigMapper mapLocationConfigMapper,
                                  ObjectMapper objectMapper) {
        this.contactInfoMapper = contactInfoMapper;
        this.mapLocationConfigMapper = mapLocationConfigMapper;
        this.objectMapper = objectMapper;
    }

    // ==================== 前端展示接口实现 ====================

    @Override
    @Transactional(readOnly = true)
    public List<ContactInfoVO> getPublicContactInfoList() {
        // 使用关联查询方法获取包含地图位置的数据
        List<ContactInfo> contactInfoList = contactInfoMapper.selectPublicWithMapLocation();
        return contactInfoList.stream()
                             .map(this::convertToVO)
                             .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public List<ContactInfoVO> getContactInfoByType(String type) {
        if (!StringUtils.hasText(type)) {
            throw new BusinessException("联系方式类型不能为空");
        }

        QueryWrapper<ContactInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 1)
               .eq("is_public", 1)
               .eq("type", type)
               .orderByAsc("display_order", "sort_order");
        
        List<ContactInfo> contactInfoList = contactInfoMapper.selectList(wrapper);
        // 手动加载地图位置信息
        return contactInfoList.stream()
                             .map(this::convertToVOWithMapLocation)
                             .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public List<ContactInfoVO> getPrimaryContactInfo() {
        QueryWrapper<ContactInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 1)
               .eq("is_public", 1)
               .eq("is_primary", 1)
               .orderByAsc("display_order", "sort_order");
        
        List<ContactInfo> contactInfoList = contactInfoMapper.selectList(wrapper);
        // 手动加载地图位置信息
        return contactInfoList.stream()
                             .map(this::convertToVOWithMapLocation)
                             .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public ContactInfoVO getContactInfoDetail(Long id) {
        if (id == null) {
            throw new BusinessException("联系信息ID不能为空");
        }

        ContactInfo contactInfo = contactInfoMapper.selectByIdWithMapLocation(id);
        if (contactInfo == null || contactInfo.getStatus() == -1) {
            throw new BusinessException("联系信息不存在");
        }

        return convertToVO(contactInfo);
    }

    // ==================== 管理端接口实现 ====================

    @Override
    @Transactional(readOnly = true)
    public PageResult<ContactInfoVO> getContactInfoPage(Long current, Long size, String keyword, String type, Integer status) {
        // 创建分页对象
        Page<ContactInfo> page = new Page<>(current, size);
        
        // 状态处理，默认不显示已删除的
        Integer finalStatus = status;
        if (status == null) {
            finalStatus = null; // 让Mapper处理默认逻辑
        }
        
        // 构建查询条件，使用普通分页查询
        QueryWrapper<ContactInfo> wrapper = new QueryWrapper<>();
        
        // 关键词搜索（标题或描述）
        if (StringUtils.hasText(keyword)) {
            wrapper.and(qw -> qw.like("title", keyword).or().like("description", keyword));
        }
        
        // 类型筛选
        if (StringUtils.hasText(type)) {
            wrapper.eq("type", type);
        }
        
        // 状态筛选
        if (finalStatus != null) {
            wrapper.eq("status", finalStatus);
        } else {
            wrapper.ne("status", -1); // 默认不显示已删除的
        }
        
        // 排序
        wrapper.orderByDesc("is_primary")
               .orderByAsc("display_order")
               .orderByAsc("sort_order")
               .orderByDesc("create_time");
        
        // 执行分页查询
        IPage<ContactInfo> pageResult = contactInfoMapper.selectPage(page, wrapper);
        
        // 转换为VO并手动加载地图位置信息
        List<ContactInfoVO> voList = pageResult.getRecords().stream()
                                              .map(this::convertToVO)
                                              .collect(Collectors.toList());
        
        return PageResult.<ContactInfoVO>builder()
                .current(pageResult.getCurrent())
                .size(pageResult.getSize())
                .total(pageResult.getTotal())
                .pages(pageResult.getPages())
                .records(voList)
                .build();
    }

    @Override
    @Transactional(readOnly = true)
    public List<ContactInfoVO> getAllContactInfoList() {
        QueryWrapper<ContactInfo> wrapper = new QueryWrapper<>();
        wrapper.ne("status", -1)
               .orderByAsc("display_order", "sort_order");
        
        List<ContactInfo> contactInfoList = contactInfoMapper.selectList(wrapper);
        return contactInfoList.stream()
                             .map(this::convertToVOWithMapLocation)
                             .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public ContactInfoVO getContactInfoById(Long id) {
        if (id == null) {
            throw new BusinessException("联系信息ID不能为空");
        }

        ContactInfo contactInfo = contactInfoMapper.selectByIdWithMapLocation(id);
        if (contactInfo == null) {
            throw new BusinessException("联系信息不存在");
        }

        return convertToVO(contactInfo);
    }

    @Override
    public ContactInfoVO createContactInfo(ContactInfoVO contactInfoVO) {
        if (contactInfoVO == null) {
            throw new BusinessException("联系信息数据不能为空");
        }

        // 验证必填字段
        if (!StringUtils.hasText(contactInfoVO.getTitle())) {
            throw new BusinessException("联系方式标题不能为空");
        }
        if (!StringUtils.hasText(contactInfoVO.getType())) {
            throw new BusinessException("联系方式类型不能为空");
        }

        ContactInfo contactInfo = new ContactInfo();
        BeanUtils.copyProperties(contactInfoVO, contactInfo);
        
        // 处理JSON字段
        try {
            if (contactInfoVO.getContentList() != null && !contactInfoVO.getContentList().isEmpty()) {
                String contentJson = objectMapper.writeValueAsString(contactInfoVO.getContentList());
                contactInfo.setContent(contentJson);
            }
        } catch (Exception e) {
            log.error("转换content为JSON失败", e);
            throw new BusinessException("联系方式内容格式错误");
        }
        
        // 设置默认值
        contactInfo.setStatus(1);
        contactInfo.setCreateTime(LocalDateTime.now());
        contactInfo.setUpdateTime(LocalDateTime.now());
        
        int result = contactInfoMapper.insert(contactInfo);
        if (result <= 0) {
            throw new BusinessException("创建联系信息失败");
        }
        
        return getContactInfoById(contactInfo.getId());
    }

    @Override
    public ContactInfoVO updateContactInfo(Long id, ContactInfoVO contactInfoVO) {
        if (id == null) {
            throw new BusinessException("联系信息ID不能为空");
        }
        if (contactInfoVO == null) {
            throw new BusinessException("联系信息数据不能为空");
        }

        ContactInfo existingContactInfo = contactInfoMapper.selectById(id);
        if (existingContactInfo == null) {
            throw new BusinessException("联系信息不存在");
        }

        // 更新字段
        BeanUtils.copyProperties(contactInfoVO, existingContactInfo);
        existingContactInfo.setId(id);
        
        // 处理JSON字段
        try {
            if (contactInfoVO.getContentList() != null) {
                String contentJson = objectMapper.writeValueAsString(contactInfoVO.getContentList());
                existingContactInfo.setContent(contentJson);
            }
        } catch (Exception e) {
            log.error("转换content为JSON失败", e);
            throw new BusinessException("联系方式内容格式错误");
        }
        
        existingContactInfo.setUpdateTime(LocalDateTime.now());
        
        int result = contactInfoMapper.updateById(existingContactInfo);
        if (result <= 0) {
            throw new BusinessException("更新联系信息失败");
        }
        
        return getContactInfoById(id);
    }

    @Override
    public Boolean deleteContactInfo(Long id) {
        if (id == null) {
            throw new BusinessException("联系信息ID不能为空");
        }

        ContactInfo contactInfo = contactInfoMapper.selectById(id);
        if (contactInfo == null) {
            throw new BusinessException("联系信息不存在");
        }

        // 软删除
        contactInfo.setStatus(-1);
        contactInfo.setUpdateTime(LocalDateTime.now());
        
        int result = contactInfoMapper.updateById(contactInfo);
        return result > 0;
    }

    @Override
    public Boolean batchDeleteContactInfo(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new BusinessException("联系信息ID列表不能为空");
        }

        List<ContactInfo> contactInfoList = contactInfoMapper.selectBatchIds(ids);
        if (contactInfoList.isEmpty()) {
            throw new BusinessException("未找到要删除的联系信息");
        }

        // 批量软删除
        LocalDateTime now = LocalDateTime.now();
        contactInfoList.forEach(contactInfo -> {
            contactInfo.setStatus(-1);
            contactInfo.setUpdateTime(now);
        });

        int updatedCount = 0;
        for (ContactInfo contactInfo : contactInfoList) {
            updatedCount += contactInfoMapper.updateById(contactInfo);
        }

        return updatedCount == contactInfoList.size();
    }

    @Override
    public Boolean updateContactInfoStatus(Long id, Integer status) {
        if (id == null) {
            throw new BusinessException("联系信息ID不能为空");
        }
        if (status == null) {
            throw new BusinessException("状态值不能为空");
        }

        ContactInfo contactInfo = contactInfoMapper.selectById(id);
        if (contactInfo == null) {
            throw new BusinessException("联系信息不存在");
        }

        contactInfo.setStatus(status);
        contactInfo.setUpdateTime(LocalDateTime.now());
        
        int result = contactInfoMapper.updateById(contactInfo);
        return result > 0;
    }

    @Override
    public Boolean setPrimaryContactInfo(Long id, Integer isPrimary) {
        if (id == null) {
            throw new BusinessException("联系信息ID不能为空");
        }
        if (isPrimary == null) {
            throw new BusinessException("主要联系方式标记不能为空");
        }

        ContactInfo contactInfo = contactInfoMapper.selectById(id);
        if (contactInfo == null) {
            throw new BusinessException("联系信息不存在");
        }

        contactInfo.setIsPrimary(isPrimary);
        contactInfo.setUpdateTime(LocalDateTime.now());
        
        int result = contactInfoMapper.updateById(contactInfo);
        return result > 0;
    }

    @Override
    public Boolean setPublicContactInfo(Long id, Integer isPublic) {
        if (id == null) {
            throw new BusinessException("联系信息ID不能为空");
        }
        if (isPublic == null) {
            throw new BusinessException("公开显示标记不能为空");
        }

        ContactInfo contactInfo = contactInfoMapper.selectById(id);
        if (contactInfo == null) {
            throw new BusinessException("联系信息不存在");
        }

        contactInfo.setIsPublic(isPublic);
        contactInfo.setUpdateTime(LocalDateTime.now());
        
        int result = contactInfoMapper.updateById(contactInfo);
        return result > 0;
    }

    @Override
    public Boolean updateDisplayOrder(Long id, Integer displayOrder) {
        if (id == null) {
            throw new BusinessException("联系信息ID不能为空");
        }
        if (displayOrder == null) {
            throw new BusinessException("显示顺序不能为空");
        }

        ContactInfo contactInfo = contactInfoMapper.selectById(id);
        if (contactInfo == null) {
            throw new BusinessException("联系信息不存在");
        }

        contactInfo.setDisplayOrder(displayOrder);
        contactInfo.setUpdateTime(LocalDateTime.now());
        
        int result = contactInfoMapper.updateById(contactInfo);
        return result > 0;
    }

    // ==================== 私有方法 ====================

    /**
     * 转换为VO对象
     */
    private ContactInfoVO convertToVO(ContactInfo contactInfo) {
        ContactInfoVO vo = new ContactInfoVO();
        BeanUtils.copyProperties(contactInfo, vo);
        
        // 设置类型显示名称
        vo.setTypeDisplay(TYPE_DISPLAY_MAP.getOrDefault(contactInfo.getType(), contactInfo.getType()));
        
        // 转换布尔字段
        vo.setIsPrimary(contactInfo.getIsPrimary() != null && contactInfo.getIsPrimary() == 1);
        vo.setIsPublic(contactInfo.getIsPublic() != null && contactInfo.getIsPublic() == 1);
        
        // 状态显示
        vo.setStatusDisplay(getStatusDisplay(contactInfo.getStatus()));
        
        // 解析JSON内容
        try {
            if (StringUtils.hasText(contactInfo.getContent())) {
                List<String> contentList = objectMapper.readValue(
                    contactInfo.getContent(), 
                    new TypeReference<List<String>>() {}
                );
                vo.setContentList(contentList);
            }
        } catch (Exception e) {
            log.error("解析content JSON失败: {}", contactInfo.getContent(), e);
        }

        // 获取地图位置信息（如果有mapLocationId）
        if (contactInfo.getMapLocationId() != null) {
            log.info("🗺️ 联系信息ID {} 关联地图位置ID: {}", contactInfo.getId(), contactInfo.getMapLocationId());
            MapLocationConfig mapLocationConfig = mapLocationConfigMapper.selectById(contactInfo.getMapLocationId());
            if (mapLocationConfig != null) {
                log.info("✅ 成功加载地图位置配置: {}, 坐标: [{}, {}]", 
                    mapLocationConfig.getTitle(), mapLocationConfig.getLongitude(), mapLocationConfig.getLatitude());
                MapLocationConfigVO mapLocationVO = new MapLocationConfigVO();
                BeanUtils.copyProperties(mapLocationConfig, mapLocationVO);
                vo.setMapLocation(mapLocationVO);
                log.info("📦 地图位置VO设置完成: {}", mapLocationVO.getTitle());
            } else {
                log.warn("❌ 未找到地图位置配置，ID: {}", contactInfo.getMapLocationId());
            }
        } else {
            log.info("📍 联系信息ID {} 未关联地图位置", contactInfo.getId());
        }
        
        return vo;
    }

    /**
     * 转换为VO对象，包含地图位置信息
     */
    private ContactInfoVO convertToVOWithMapLocation(ContactInfo contactInfo) {
        ContactInfoVO vo = new ContactInfoVO();
        BeanUtils.copyProperties(contactInfo, vo);
        
        // 设置类型显示名称
        vo.setTypeDisplay(TYPE_DISPLAY_MAP.getOrDefault(contactInfo.getType(), contactInfo.getType()));
        
        // 转换布尔字段
        vo.setIsPrimary(contactInfo.getIsPrimary() != null && contactInfo.getIsPrimary() == 1);
        vo.setIsPublic(contactInfo.getIsPublic() != null && contactInfo.getIsPublic() == 1);
        
        // 状态显示
        vo.setStatusDisplay(getStatusDisplay(contactInfo.getStatus()));
        
        // 解析JSON内容
        try {
            if (StringUtils.hasText(contactInfo.getContent())) {
                List<String> contentList = objectMapper.readValue(
                    contactInfo.getContent(), 
                    new TypeReference<List<String>>() {}
                );
                vo.setContentList(contentList);
            }
        } catch (Exception e) {
            log.error("解析content JSON失败: {}", contactInfo.getContent(), e);
        }

                 // 获取地图位置信息
         if (contactInfo.getMapLocationId() != null) {
             MapLocationConfig mapLocationConfig = mapLocationConfigMapper.selectById(contactInfo.getMapLocationId());
             if (mapLocationConfig != null) {
                 MapLocationConfigVO mapLocationVO = new MapLocationConfigVO();
                 BeanUtils.copyProperties(mapLocationConfig, mapLocationVO);
                 vo.setMapLocation(mapLocationVO);
             }
         }
        
        return vo;
    }

    /**
     * 获取状态显示文本
     */
    private String getStatusDisplay(Integer status) {
        if (status == null) return "未知";
        switch (status) {
            case 1: return "启用";
            case 0: return "禁用";
            case -1: return "已删除";
            default: return "未知";
        }
    }
} 
